import win32api
import win32gui
import win32con
import pythoncom
import time
import win32com
import win32clipboard as cp
from win32com.client import Dispatch



class CallWechat(object):
    def __init__(self, receiver_name):
        self.receiver_name = receiver_name
        self.className = 'WeChatMainWndForPC'

    """
    配置要打电话对象的姓名变量
    """
    def set_name(self):
        cp.OpenClipboard()
        cp.EmptyClipboard()
        cp.SetClipboardData(win32con.CF_UNICODETEXT, self.receiver_name)
        cp.CloseClipboard()
        return

    # SetClipboardData方法向剪贴板写入数据，后面两个参数，第一个表示数据类型，
    # 建议使用win32con.CF_UNICODETEXT，这样基本可以原样输出我们传入的数据
    # 如果使用win32con.CF_TEXT: 输出的是字节码

    def CtrlV(self):
        win32api.keybd_event(17, 0, 0, 0)  # ctrl
        win32api.keybd_event(86, 0, 0, 0)  # V
        win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0)  # 释放按键
        win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0)

    def click(self):
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)

    def movePos(self, x, y):
        win32api.SetCursorPos((x, y))

    def enter(self):
        win32api.keybd_event(13, 0, 0, 0)  # enter
        win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0)

    def get_window(self):
        win = win32gui.FindWindow("WeChatMainWndForPC", "微信")  # param1需要传入窗口的类名，param2需要传入窗口的标题 获取窗口句柄
        if win != 0:
            win32gui.ShowWindow(win, win32con.SW_SHOW)  # SW_SHOW：在窗口原来的位置以原来的尺寸激活和显示窗口
            # pythoncom.CoInitialize()  # 拿来用在windows多线程 使用win32 com的情况下，进行简单的初始化，但是也没有看见后面的CoUninitialize(),我感觉这个东西在这里是没有用的
            # shell = win32com.client.Dispatch("WScript.Shell")
            # shell.SendKeys('%')
            win32gui.SetForegroundWindow(win)  # 获取控制 将窗口现实在最前面
            win32gui.MoveWindow(win, 0, 0, 1000, 700, True)  # 移动窗口的位置到左上角 方便后续的坐标位置的确定
            time.sleep(0.5)
            return
        else:
            print("找不到微信主窗口")

    def choose_window(self):
        Frame_childclass = "WeChatMainWndForPC"
        Frame_childtitle = "微信"
        desktop_window = win32gui.GetDesktopWindow()  # 获取桌面窗口 作为父窗口 从而逐层去查找 形同类名的子窗口
        window = desktop_window
        hwndChild = None
        while True:
            hwndChild = win32gui.FindWindowEx(desktop_window, hwndChild, Frame_childclass, Frame_childtitle)
            if hwndChild:
                print("window:%d" % hwndChild)
                print("class:%s" % win32gui.GetClassName(hwndChild))
                print("title:%s" % win32gui.GetWindowText(hwndChild))
            else:
                return

# 获得微信界面句柄
    def get_window_call(self):
        Frame_class = "VoipTrayWnd"
        Frame_title = "微信"
        win = win32gui.FindWindow(Frame_class, Frame_title)
        win32gui.ShowWindow(win, win32con.SW_SHOW)
        win32gui.SetForegroundWindow(win)  # 获取控制 将窗口现实在最前面
        time.sleep(1)
        return

# 获得关闭微信界面句柄
    def close_window_call(self):
        Frame_class = "AudioWnd"
        Frame_title = "微信"
        win = win32gui.FindWindow(Frame_class, Frame_title)
        if win != 0:
            win32gui.ShowWindow(win, win32con.SW_SHOW)
            win32gui.SetForegroundWindow(win)
            time.sleep(1)
            return 1
        else:
            return 0

# 进行拨打电话的操作
    def call(self):  # 这些位置坐标都可以通过微信截图来进行坐标点的确定 若第一次可选择先点击通讯录 再进行后续操作，如果已经打开，则后续操作可以不进行点击通讯录的操作
        self.get_window()
        self.movePos(28, 147)  # 移动到微信通信录处
        self.click()
        self.movePos(148, 35)  # 移动到搜索框处
        self.click()
        self.set_name()
        self.CtrlV()
        time.sleep(1)
        self.enter()
        time.sleep(1)
        self.movePos(931, 579)  # 移动到打电话的小按钮处
        self.click()

# 进行应答电话的操作
    def answer(self):  # 应答弹窗 在右下角
        self.get_window_call()
        self.movePos(1881, 1010)
        self.click()
# 挂电话
    def close_call(self):
        if self.close_window_call() != 0:
            self.movePos(1189, 525)
            self.click()
            return


# 在设计各个界面的选中过程中 可以使用win32gui.SetForegroundWindow(win)  # 获取控制 将窗口现实在最前面 但要先获取窗口句柄
# 整个的一个打电话 接电话 持续一段时间 然后挂掉电话 然后再循环过来 整个过程应当是具有较为明显的前后的逻辑关系的

if __name__ == '__main__':
    count = 1
    while count <= 2:
        wechat_call = CallWechat("wechatname")  # 考虑是给同一个人一直打电话 然后采集数据 还是说给多个人打电话采集数据 然后这个循环的次数怎么确定，如何跟sniff进行一个同步
        wechat_call.call()
        time.sleep(30)
        wechat_call.close_call()
        count = count+1


# 需要测试看走Tor代理打一次电话 会存在多少的延迟 然后这个通话时间应该确定为多少
# 看需要进行多少次实验啥的

# 考虑到需要将打电话以及接电话放在两个位置上进行操作，需要重新写一个监听接电话行为的一个程序
# 可以轮训地不停访问是否存在这个窗口 如果存在则进行后续的操作 并在操作完成后 静默2s 然后不停的轮训
# 接电话的机子 只做接电话操作 并不做其他操作  就相当于一直轮训 直到有反应位置